package com.example.demospringboot.netty.custom.ecodc;

import com.alibaba.fastjson.JSON;
import com.example.demospringboot.netty.custom.procotol.ComPack;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author chenlei
 * @date 2020/1/16
 * @description 接收数据的解码器，decode方法会被重复调用
 **/
public class ByteToComPackDecoder extends ByteToMessageDecoder {

    private Logger log = LoggerFactory.getLogger(getClass());

    //头长度的字节数
    private final static int DEFAULT_HEAD_LENTH=4;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> list) throws Exception {
        log.info("当前线程名"+Thread.currentThread().getName()+this);
        //小于头长度的字节数不读取
        if(byteBuf.readableBytes()<DEFAULT_HEAD_LENTH){
            return;
        }
        //标记读取的位置
        byteBuf.markReaderIndex();
        int length = byteBuf.readInt();// 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4
        // 我们读到的消息体长度为0，这是不应该出现的情况，这里出现这情况，关闭连接。
        if (length < 0) {
            ctx.close();
        }
        //读到的消息体长度如果小于我们传送过来的消息长度，则resetReaderIndex. 这个配合markReaderIndex使用的。把readIndex重置到mark的地方
        if (byteBuf.readableBytes() < length) {
            byteBuf.resetReaderIndex();
            return;
        }
        //读取消息
        String body = byteBuf.readBytes(length).toString(CharsetUtil.UTF_8);
        log.info("接收到请求信息:"+body);
        ComPack comPack = JSON.parseObject(body, ComPack.class);
        list.add(comPack);
    }
}
